package com.songxh.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mysql.cj.x.protobuf.MysqlxDatatypes;
import com.songxh.pojo.Admin;
import com.songxh.pojo.LoginFrom;
import com.songxh.pojo.Student;
import com.songxh.pojo.Teacher;
import com.songxh.service.AdminService;
import com.songxh.service.StudentService;
import com.songxh.service.TeacherService;
import com.songxh.utils.*;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Set;
import java.util.UUID;

/**
 * 用来写与表数据无关的操作，如登录、验证码等
 *
 * @author songxh
 * @create 2022-04-18-19:36
 */
@RestController
@RequestMapping("/sms/system")
public class SystemController {

    @Autowired
    private AdminService adminService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private TeacherService teacherService;


    //登录验证
    @ApiOperation("登录验证")
    @PostMapping("/login")
    public Result login(@RequestBody LoginFrom loginFrom, HttpServletRequest request){
        //验证码校验
        String loginVerifiCode = loginFrom.getVerifiCode();
        HttpSession session = request.getSession();
        String sessionVerifiCode = (String)session.getAttribute("verifiCode");
        if (sessionVerifiCode==null || "".equals(sessionVerifiCode)){
            return Result.fail().message("验证码为空，请刷新后重新填写");
        }
        if (!sessionVerifiCode.equalsIgnoreCase(loginVerifiCode)){
            return Result.fail().message("验证码错误，请刷新后重新填写");
        }
        //每次错误之后，将session清空
        session.removeAttribute("verifiCode");

        //分用户类型校验
        HashMap<String,Object> map=new LinkedHashMap<>();
        switch (loginFrom.getUserType()){
            case 1:
                try {
                    //管理员用户
                    Admin admin=adminService.login(loginFrom);
                    if (null!=admin){
                        String token = JwtHelper.createToken(admin.getId().longValue(), 1);
                        //因为前端已经约定俗成了一套规范，需要将token放入一个map集合里
                        map.put("token",token);
                    }else {
                        //如何校验失败，返回一个异常
                        throw new RuntimeException("用户名或者密码有误");
                    }
                    return Result.ok(map);
                } catch (RuntimeException e) {
                    e.printStackTrace();
                    return Result.fail().message(e.getMessage());
                }
            case 2:
                try {
                    //学生用户
                    Student student=studentService.login(loginFrom);
                    if (null!=student){
                        String token = JwtHelper.createToken(student.getId().longValue(), 2);
                        //因为前端已经约定俗成了一套规范，需要将token放入一个map集合里
                        map.put("token",token);
                    }else {
                        //如何校验失败，返回一个异常
                        throw new RuntimeException("用户名或者密码有误");
                    }
                    return Result.ok(map);
                } catch (RuntimeException e) {
                    e.printStackTrace();
                    return Result.fail().message(e.getMessage());
                }
            case 3:
                try {
                    //教师用户
                    Teacher teacher=teacherService.login(loginFrom);
                    if (null!=teacher){
                        String token = JwtHelper.createToken(teacher.getId().longValue(), 3);
                        //因为前端已经约定俗成了一套规范，需要将token放入一个map集合里,然后返回给前端
                        map.put("token",token);
                    }else {
                        //如何校验失败，返回一个异常
                        throw new RuntimeException("用户名或者密码有误");
                    }
                    return Result.ok(map);
                } catch (RuntimeException e) {
                    e.printStackTrace();
                    return Result.fail().message(e.getMessage());
                }
        }

        return Result.fail().message("没有查找到此用户");
    }


    /**
     * @RequestHeader 表示在请求头中获取数据
     * @param token
     * @return
     */
    @ApiOperation("判断不同用户类型进入不同界面")
    @GetMapping("/getInfo")
    public Result getInfoByToken(@RequestHeader String token){

        //判断token是否失效
        if (JwtHelper.isExpiration(token)) {
            //返回true，表示已经失效
            return Result.build(null, ResultCodeEnum.TOKEN_ERROR);
        }
        //获取token中的id 和用户名
        Long id = JwtHelper.getUserId(token);
        Integer type = JwtHelper.getUserType(token);

        //因为前端已经约定好要将usertype和user存放在map集合中
        HashMap<String,Object> map=new LinkedHashMap<>();
        switch (type){
            case 1:
                Admin admin=adminService.getAdminById(id);
                map.put("userType",1);
                map.put("user",admin);
                break;
            case 2:
                Student student=studentService.getStudentById(id);
                map.put("userType",2);
                map.put("user",student);
                break;
            case 3:
                Teacher teacher=teacherService.getTeacherById(id);
                map.put("userType",3);
                map.put("user",teacher);
                break;
        }

        return Result.ok(map);
    }


    //验证码
    @ApiOperation("验证码的获取")
    @GetMapping("/getVerifiCodeImage")
    public void getVerifiCodeImage(HttpServletRequest request, HttpServletResponse response){
        //获取图片
        BufferedImage verifiCodeImage = CreateVerifiCodeImage.getVerifiCodeImage();
        //获取图片上的验证码文字
        String verifiCode=new String(CreateVerifiCodeImage.getVerifiCode());
        //将验证码文本放入session域中
        HttpSession session = request.getSession();
        session.setAttribute("verifiCode",verifiCode);
        //将验证码图片响应给浏览器
        try {
            ImageIO.write(verifiCodeImage,"JPEG",response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @ApiOperation("头像上传功能")
    @PostMapping("/headerImgUpload")
    public Result headerImgUpload(
            @ApiParam("头像图片") @RequestPart("multipartFile") MultipartFile multipartFile
    ){
        //为了让每一个头像图片的名字不同，使用uuid
        String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
        String originalFilename = multipartFile.getOriginalFilename();
        int i = originalFilename.lastIndexOf(".");
        String newFileName = uuid+originalFilename.substring(i);

        //保存文件
        String portraitPath="C:/Users/HYGK-PC/IdeaProjects/springboot-zhxy/target/classes/public/upload/"+newFileName;
        try {
            multipartFile.transferTo(new File(portraitPath));
        } catch (IOException e) {
            e.printStackTrace();
        }

        //图片存在的路劲
        String path="upload/"+newFileName;
        return Result.ok(path);
    }


    @ApiOperation("修改密码")
    @PostMapping("/updatePwd/{oldPwd}/{newPwd}")
    public Result updatePwd(
            @ApiParam("原密码")
            @PathVariable("oldPwd")String oldPwd,
            @ApiParam("新密码")
            @PathVariable("newPwd")String newPwd,
            @ApiParam("获取请求头参数")
            @RequestHeader("token")String token
    ) {
        boolean expiration = JwtHelper.isExpiration(token);
        if (expiration) {
            Result.fail().message("token失效，请重新登录");
        }
        Long userId = JwtHelper.getUserId(token);
        Integer userType = JwtHelper.getUserType(token);

        oldPwd = MD5.encrypt(oldPwd);
        newPwd=MD5.encrypt(newPwd);


        switch (userType){
            case 1:
                QueryWrapper<Admin> queryWrapper=new QueryWrapper<>();
                queryWrapper.eq("id",userId.intValue());
                queryWrapper.eq("password",oldPwd);
                Admin admin=adminService.getOne(queryWrapper);
                if (admin!=null){
                    admin.setPassword(newPwd);
                    adminService.saveOrUpdate(admin);
                }else {
                    return Result.fail().message("请输入正确的密码");
                }
                break;
            case 2:
                QueryWrapper<Student> queryWrapper2=new QueryWrapper<>();
                queryWrapper2.eq("id",userId);
                queryWrapper2.eq("password",oldPwd);
                Student student=studentService.getOne(queryWrapper2);
                if (student!=null){
                    student.setPassword(newPwd);
                    studentService.saveOrUpdate(student);
                }else {
                    return Result.fail().message("请输入正确的密码");
                }
                break;
            case 3:
                QueryWrapper<Teacher> queryWrapper3=new QueryWrapper<>();
                queryWrapper3.eq("id",userId);
                queryWrapper3.eq("password",oldPwd);
                Teacher teacher=teacherService.getOne(queryWrapper3);
                if (teacher!=null){
                    teacher.setPassword(newPwd);
                    teacherService.saveOrUpdate(teacher);
                }else {
                    return Result.fail().message("请输入正确的密码");
                }
                break;
        }
        return Result.ok();
    }
}
